package cn.itsource.pet.service.impl;

import cn.itsource.basic.config.BussinessException;
import cn.itsource.basic.domain.Point;
import cn.itsource.basic.util.*;
import cn.itsource.order.domain.OrderPetAcquisition;
import cn.itsource.order.service.IOrderPetAcquisitionService;
import cn.itsource.org.domain.Employee;
import cn.itsource.org.domain.Shop;
import cn.itsource.org.service.IEmployeeService;
import cn.itsource.org.service.IShopService;
import cn.itsource.pet.domain.SearchMasterMsg;
import cn.itsource.pet.domain.SearchMasterMsgAuditLog;
import cn.itsource.pet.domain.SearchMasterMsgRejectLog;
import cn.itsource.pet.dto.AcceptDto;
import cn.itsource.pet.mapper.SearchMasterMsgMapper;
import cn.itsource.pet.query.SearchMasterMsgQuery;
import cn.itsource.pet.service.ISearchMasterMsgAuditLogService;
import cn.itsource.pet.service.ISearchMasterMsgRejectLogService;
import cn.itsource.pet.service.ISearchMasterMsgService;
import cn.itsource.basic.service.impl.BaseServiceImpl;
import org.apache.commons.lang3.StringUtils;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author itsource
 * @since 2022-11-01
 */
@Service
public class SearchMasterMsgServiceImpl extends BaseServiceImpl<SearchMasterMsg> implements ISearchMasterMsgService {
    @Autowired
    private SearchMasterMsgMapper searchMasterMsgMapper;
    @Autowired
    private ISearchMasterMsgAuditLogService searchMasterMsgAuditLogService;
    @Autowired
    private IShopService shopService;
    @Autowired
    private IEmployeeService employeeService;
    @Autowired
    private IOrderPetAcquisitionService orderPetAcquisitionService;
    @Autowired
    private ISearchMasterMsgRejectLogService searchMasterMsgRejectLogService;
    @Autowired
    private RocketMQTemplate rocketMQTemplate;

    /**
     * 发布寻主业务
     * @param searchMasterMsg
     * @return
     */
    @Override
    public AjaxResult publish(SearchMasterMsg searchMasterMsg) {
        // 1.保存数据库，设置状态为待审核
        searchMasterMsg.setState(0);
        searchMasterMsgMapper.add(searchMasterMsg);
        // 2.非空校验，失败保存原因导数据库日志表
        paramCheck(searchMasterMsg);
        // 3.百度AI智能审核
        // 3.1 审核成功
        StringBuilder stringBuilder = getStringBuilder(searchMasterMsg);
        if (BaiduAuditUtils.TextCensor(stringBuilder.toString())) {
            // 3.1.1 匹配最近的店铺，设置shopId，如果没有50KM以内就放到寻主池
            List<Shop> shops = shopService.findAll();
            Point point = DistanceUtils.getPoint(searchMasterMsg.getAddress());
            Shop nearestShop = DistanceUtils.getNearestShop(point, shops);
            if (null != nearestShop) {
                searchMasterMsg.setShopId(nearestShop.getId());
            }
            // 3.1.2 修改状态及备注
            searchMasterMsg.setState(1);
            searchMasterMsg.setNote("审核通过");
            // 3.1.3 修改数据库信息
            searchMasterMsgMapper.update(searchMasterMsg);
        } else {
            // 3.2 审核失败【添加原因note到日志表，并且返回给前端】
            SearchMasterMsgAuditLog searchMasterMsgAuditLog = new SearchMasterMsgAuditLog();
            searchMasterMsgAuditLog.setMsgId(searchMasterMsg.getId());
            searchMasterMsgAuditLog.setState(0);
            searchMasterMsgAuditLog.setAuditId(3l);
            searchMasterMsgAuditLog.setNote("信息涉及违规，审核失败，请在个人中心中进行修改发布！");
            searchMasterMsgAuditLogService.add(searchMasterMsgAuditLog);
            throw new BussinessException("信息涉及违规，审核失败，请在个人中心中进行修改发布！");
        }
        return AjaxResult.me().success();
    }

    @Override
    public PageList<SearchMasterMsg> selectSearchMasterMessageByParam(SearchMasterMsgQuery searchMasterMsgQuery) {
        // 查询总天数
        Integer totals = searchMasterMsgMapper.selectSearchMasterMessageByParamQuery(searchMasterMsgQuery);
        if (totals == null || totals == 0) {
            return new PageList<>(0, new ArrayList<>());
        }
        List<SearchMasterMsg> searchMasterMsgs = searchMasterMsgMapper.selectSearchMasterMessageByParam(searchMasterMsgQuery);
        return new PageList<>(totals, searchMasterMsgs);
    }

    /**
     * 接单接口
     * @param acceptDto
     */
    @Override
    public void accept(AcceptDto acceptDto) {
        // 1. 根据msgId查询虚竹消息
        SearchMasterMsg searchMasterMsg = searchMasterMsgMapper.findById(acceptDto.getMsgId());
        // 2.非空校验
        if (searchMasterMsg == null ){
            throw new BussinessException("消息不能为空");
        }
        // 3.上锁解决线程高并发问题，防止多个员工抢单
        synchronized (searchMasterMsg.getId()) {
            // 查询接单的员工信息，并获取他所在的店铺信息
            Employee employee = employeeService.findById(acceptDto.getHandler());
            // 校验
            if (employee == null) {
                throw new BussinessException("不存在此员工！");
            }
            // 如果寻主消息为审核通过了并且此员工是寻主消息中的店铺员工
            if (searchMasterMsg.getState() == 1 && employee.getShopId().equals(searchMasterMsg.getShopId())) {
                // 那么就把寻主消息的状态设置为2
                searchMasterMsg.setState(2);
                searchMasterMsgMapper.update(searchMasterMsg);
                // 初始化收购单
                initOrder(acceptDto, searchMasterMsg, employee);

            }
        }
    }


    /**
     * 拒单
     * @param msgId
     * @param employee
     */
    @Override
    public void reject(Long msgId, Employee employee) {
        // 校验
        SearchMasterMsg searchMasterMsg = searchMasterMsgMapper.findById(msgId);
        if (searchMasterMsg == null) {
            throw new BussinessException("寻主消息不能为空");
        }
        // 拒单就让它的shopId置空，放到寻主池
        searchMasterMsg.setShopId(null);
        // 添加拒单日志
        initRejectLog(msgId, employee);
    }

    /**
     * 添加拒单日志
     * @param msgId
     * @param employee
     */
    private void initRejectLog(Long msgId, Employee employee) {
        SearchMasterMsgRejectLog searchMasterMsgRejectLog = new SearchMasterMsgRejectLog();
        searchMasterMsgRejectLog.setMsgId(msgId);
        searchMasterMsgRejectLog.setRejecterId(employee.getId());
        searchMasterMsgRejectLog.setState(1);
        searchMasterMsgRejectLogService.add(searchMasterMsgRejectLog);
    }

    /**
     * 用于百度审核的文本字符串拼接
     * @param searchMasterMsg
     * @return
     */
    private StringBuilder getStringBuilder(SearchMasterMsg searchMasterMsg) {
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append(searchMasterMsg.getAddress())
                    .append(searchMasterMsg.getTitle())
                    .append(searchMasterMsg.getName());
        return stringBuilder;
    }

    /**
     * 发布寻主的非空校验
     * @param searchMasterMsg
     */
    private void paramCheck(SearchMasterMsg searchMasterMsg) {
        if (StringUtils.isEmpty(searchMasterMsg.getTitle()) || StringUtils.isEmpty(searchMasterMsg.getName()) ||
                StringUtils.isEmpty(searchMasterMsg.getAddress())) {
            SearchMasterMsgAuditLog searchMasterMsgAuditLog = new SearchMasterMsgAuditLog();
            searchMasterMsgAuditLog.setMsgId(searchMasterMsg.getId());
            searchMasterMsgAuditLog.setState(0);
            searchMasterMsgAuditLog.setAuditId(3l);
            searchMasterMsgAuditLog.setNote("标题或名字或地址不能为空");
            searchMasterMsgAuditLogService.add(searchMasterMsgAuditLog);
            throw new BussinessException("标题或名字或地址不能为空");
        }
    }

    /**
     * 初始化收购订单
     * @param acceptDto
     * @param searchMasterMsg
     * @param employee
     */
    private void initOrder(AcceptDto acceptDto, SearchMasterMsg searchMasterMsg, Employee employee) {
        OrderPetAcquisition orderPetAcquisition = new OrderPetAcquisition();
        orderPetAcquisition.setOrderSn(CodeGenerateUtils.generateOrderSn(acceptDto.getHandler()));
        orderPetAcquisition.setDigest(acceptDto.getNote());
        orderPetAcquisition.setLastcomfirmtime(new Date(System.currentTimeMillis() + 3 * 24 * 60 * 60 * 1000));
        orderPetAcquisition.setState(0);
        orderPetAcquisition.setPrice(new BigDecimal(String.valueOf(searchMasterMsg.getPrice())));
        orderPetAcquisition.setUserId(searchMasterMsg.getUserId());
        orderPetAcquisition.setShopId(employee.getShopId());
        orderPetAcquisition.setAddress(searchMasterMsg.getAddress());
        orderPetAcquisition.setEmpId(employee.getId());
        orderPetAcquisition.setSearchMasterMsgId(searchMasterMsg.getId());
        orderPetAcquisitionService.add(orderPetAcquisition);
        rocketMQTemplate.syncSend("order_topic", MessageBuilder.withPayload(orderPetAcquisition).build(),3000,5);
    }

}
